package cn.cihon.ubi.qorosauto.biz;

import cn.cihon.ubi.qorosauto.bo.TripData;
import cn.cihon.ubi.qorosauto.util.ModelPara;


public class EconDataGenerator {
	
	private ModelPara modelPara; // ModelPara.csv	
	
	private double mark_Econ; 
	private double mark_rpmPkm;
	private double Mark_WQAcc;
	private double Mark_WQDcc;
	private double Mark_WQTcc;
	private double Mark_stdAcc;

	private double Mark_IdleTime;
	
	private double ExtraEcon; 
	private double ExtraEconIdle; 
	private double FreWQAcc; // no calc
	private double FreWQDcc; // no calc
	private double FreWQTcc; // no calc
	
	private double IdleTimeG120;// no calc 
	private double ValidDataPoint; // no calc 
	private double tripLength;// no calc
	private double AvgVehSpeed;// no calc
	private double AvgEngSpeed; // no calc
	private double StdAcc; // no calc
	private double tripConsum; // no calc 
	
	public EconDataGenerator (TripData tripData) {
		
		this.modelPara = ModelPara.getInstance();
		
		// 初始化基础数据
		this.FreWQAcc = tripData.getFreWQACC();
		this.FreWQDcc = tripData.getFreWQDCC();
		this.FreWQTcc = tripData.getFreWQTCC();
		this.IdleTimeG120 = tripData.getDaisushijianchangdu() / 1000 - 120;
		this.ValidDataPoint = tripData.getYouxiaodeshujuliang();
		this.tripLength = Double.valueOf(tripData.getLichengchangdu());
		this.AvgVehSpeed = Double.valueOf(tripData.getPingjunchesu());
		this.AvgEngSpeed = Double.valueOf(tripData.getPingjunfadongjisudu());
		this.StdAcc = Double.valueOf(tripData.getAccStd());
		this.tripConsum = Double.valueOf(tripData.getZongyouhao());
		
		this.ExtraEcon = this.getExtraEcon();
		this.ExtraEconIdle = this.getExtraEconIdle();
		
		// 计算中间变量
		this.mark_Econ = this.getMark_Econ();
		this.mark_rpmPkm = this.getMark_rpmPkm();
		this.Mark_WQAcc = this.getMark_WQAcc();
		this.Mark_WQDcc = this.getMark_WQDcc();
		this.Mark_WQTcc = this.getMark_WQTcc();
		this.Mark_stdAcc = this.getMark_stdAcc();
		this.Mark_IdleTime = this.getMark_IdleTime();
	}

	// ecoPoint = (Mark_Econ * 0.3 + Mark_rpmPkm * 0.3 + Mark_WQAcc * 0.1 + Mark_WQDcc * 0.1 + Mark_WQTcc * 0.1 + Mark_stdAcc * 0.1) * Mark_IdleTime
	public double getEcoPoint() {
		return (mark_Econ * 0.3 + mark_rpmPkm * 0.3 + Mark_WQAcc * 0.1 + Mark_WQDcc * 0.1 + Mark_WQTcc * 0.1 + Mark_stdAcc * 0.1) * Mark_IdleTime;
	}

	// safePoint = Mark_WQAcc * 0.2 + Mark_WQDcc * 0.2 + Mark_WQTcc * 0.5 + Mark_stdAcc * 0.1
	public double getSafePoint() {
		return Mark_WQAcc * 0.2 + Mark_WQDcc * 0.2 + Mark_WQTcc * 0.5 + Mark_stdAcc * 0.1;
	}

	// Mark_Econ = min(max(100.0 - (ExtraEcon + ExtraEconIdle) / tripLength / 0.001,0.0), 100.0)
	public double getMark_Econ() {
		
		double tmpMark_Econ = 100.0 - (ExtraEcon + ExtraEconIdle) / tripLength / 0.001;
		
		if (tmpMark_Econ < 0)  {
			return 0;
		} 
		
		if (tmpMark_Econ > 100) {
			return 100;
		}
		
		return tmpMark_Econ;
	}

	// Mark_rpmPkm = 100 - ModelMark(AvgEngSpeed / (AvgVehSpeed + 1e-07), numpy.arrayModelPara['rpmPkm']())
	public double getMark_rpmPkm() {
		
		return 100 - this.modelPara.ModelMark(AvgEngSpeed / (AvgVehSpeed + 1e-07), "rpmPkm");
	}

	// Mark_WQAcc = 100 - ModelMark(FreWQAcc / 3.6, numpy.array(ModelPara['WQAcc']))
	public double getMark_WQAcc() {
		
		return 100 - this.modelPara.ModelMark(FreWQAcc / 3.6, "WQAcc");
	}

	// Mark_WQDcc = ModelMark(FreWQDcc / 3.6, numpy.array(ModelPara['WQDcc']))
	public double getMark_WQDcc() {
		
		return this.modelPara.ModelMark(FreWQDcc / 3.6, "WQDcc");
	}

	// Mark_WQTcc = 100 - ModelMark(FreWQTcc / 3.0, numpy.array(ModelPara['WQTcc']))
	public double getMark_WQTcc() {
		
		return 100 - this.modelPara.ModelMark(FreWQTcc / 3.0, "WQTcc");
	}

	// Mark_stdAcc = 100 - ModelMark(StdAcc * 3.6, numpy.array(ModelPara['stdAcc']))
	public double getMark_stdAcc() {
		return 100 - this.modelPara.ModelMark(StdAcc * 3.6, "stdAcc");
	}

	// Mark_IdleTime = min(max(1.0 - 1.0 * IdleTimeG120 / ValidDataPoint, 0.0), 1.0)
	public double getMark_IdleTime() {
		
		double tmp_Mark_IdleTime = 1.0 - 1.0 * this.IdleTimeG120 / this.ValidDataPoint;
		
		if (tmp_Mark_IdleTime < 0) {
			return 0;
		}
		
		if (tmp_Mark_IdleTime > 100) {
			return 100;
		}
		
		return tmp_Mark_IdleTime;
	}
	
	
	private double polyVal(double[] P, double data) {
		return P[0] * data * data * data + P[1] * data * data + P[2] * data + P[3];
	}
	
	public double getExtraEcon() {
		
		double[] P = new double[]{
				6.30386536089908e-06,
                -0.000391936653118316,
                0.0253686382877674,
                0.812763837565301};
		
		double ExtraEcon = ((1.0 * tripConsum / 100.0 * AvgVehSpeed * ValidDataPoint) / 3600.0) - polyVal(P, AvgVehSpeed) / 3600.0 * ValidDataPoint;
		
		return ExtraEcon;
	}

	public double getExtraEconIdle() {
		
		return 0.7 * IdleTimeG120 / 3600.0;
	}

}